{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Logistic 回归\n",
    "Logistic回归中，输出(Y = 1)的对数几率是输入 x 的线性函数，思路 : \n",
    "\n",
    "1. 先拟合决策边界（不局限于线性，还可以是多项式）\n",
    "2. 再建立这个边界和分类概率的关系\n",
    "3. 从而得到二分类情况下的概率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import torch\n",
    "from torch import nn\n",
    "from torch import optim\n",
    "from torch.autograd import Variable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7fe1efaed748>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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NCItNQ40jj4YOY9rdne+/OUv84Mf/IA5c+awf/9+XnjhBQBOPfVULrjgAgCuueYabrnlFi6//HJ27tzJBz7wAQDeeustlixZkkkslbRunRK7lKPX8xBCOoeiB9VI9Bs3tj47MKPD//HxcaamptixYwfz589nbGzs8Dj25qGOZoa78653vYsf/ehHPb3P8PAwBw8e5M0332TevHlMTk5yyil9nYYgIt3qpaGRc67JSzVKNzkf/r/yyiucdNJJzJ8/n0ceeYRnG/bo+/btO5zQ77zzTi688EJWrlzJ1NTU4eWHDh3iySefnPV9zIz3v//9h0flbN68mbVr12byGUQkA5GWGquR6CHX4V3r1q1jYmKCM888k29/+9ucdtpph/9t5cqV3HrrrZx++um8/PLLfOYzn+GYY45h69at3HjjjZx11lmsWrWKH/7wh129180338xXv/pVli9fzvT0NNddd11mn0NEMhDhUNKBJzXLQqtJzXbt2sXpp59eUkThi3r9jI+XOzeLSEUUMqmZSM+aZ1ucGYcMSvYiOalO6SYyV111FatWrTri9sADD5QdVv4iHYcsEjO16Ety7733lh1COSIdhywSM7XopVia8kCkcEr0UixNeSBSOCV6KVak45BFYqYavRRPUx6IFKoyLfo8poguYz76r3/96yxfvhwz48UXX+zptUVEWqlEoo90iuiWLrjgAh566CFGR0fLDkVEKqISiT7vodlFzUcPcPbZZzM2NpZN4CIiVCTR5z00u6j56EVE8lCJzti8p4jWfPQiErNKJPq8p4guaj56EZE8VKJ0k/fQ7KLmoxfpWx7DzqQy+k70ZrbAzP7JzJ4wsyfN7E/T5cvM7FEz22Nmf2tmx2QXbnt5ThFd5Hz0t9xyCyMjI0xOTvLud7+bT3/609l9EKmmKg07k1z0PR+9JTWLY939VTObD/wf4AvADcB33P1uM/tL4Al3v63Ta2k++t5p/chhY2OtO6lGR5NWj1RWt/PR992i98Sr6cP56c2Bi4GZM4I2A1f2+x4i0gXNCCqzGKgz1szmAjuA5cCtwP8DDrr7m+lTJgFd3bqFq666imeeeeaIZTfffDOXXXZZSRFJtPIedibRGyjRu/tbwCozWwjcC5w2y385zMw2ABsAltZwg6ztfPSSvbyHnUn0Mhl14+4HgUeA84GFZjazAxkB9rf5P5vcfY27r1m8eHG7180ivMrRepEjaEZQmcUgo24Wpy15zOzXgQ8Au0gS/tXp09YD21q/QmcLFixgenpaSa2JuzM9Pc2CBQvKDkVCkuewM4neIKWbJcDmtE4/B7jH3e83s6eAu83svwE/Bm7v58VnhhhOTU0NEGI1LViwgJGRkbLDEJFI9J3o3f0nwNktlv8cOHeQoADmz5/PsmXLBn0ZEZHaq8SZsSIi0p4SvYhIxSnRi4hUXN9TIGQahNkU0OKMj66cCMR0zb2Y4o0pVlC8eYopVogr3kFiHXX31uPTGwSR6AdhZhPdzPUQipjijSlWULx5iilWiCveImJV6UZEpOKU6EVEKq4KiX5T2QH0KKZ4Y4oVFG+eYooV4oo391ijr9GLiEhnVWjRi4hIB1El+tAuX9gNM5trZj82s/vTxyHHutfMfmpmj5vZRLrsBDN70MyeTu8XlR0ngJktNLOtZvYzM9tlZucHHOvKdJ3O3P7FzL4YarwAZnZ9+hvbaWZ3pb+9ILddM/tCGueTZvbFdFkw69bMvmlmB8xsZ8OylvFZ4pZ0Hf/EzM7JIoaoEj3wb8DF7n4WsAq43MzOA24G/tzdlwMvA9eVGGOzL5DM6jkj5FgB3u/uqxqGe90EbHf3FcD29HEIvgZ8z91PA84iWcdBxuruu9N1ugpYDbxGcv2GIOM1s1OAPwLWuPsZwFzg4wS47ZrZGcAfksyvdRZwhZktJ6x1+zfA5U3L2sX3IWBFetsAdLwMa9fcPcobMAQ8BryH5GSDeeny84EHyo4vjWUk/RIvBu4HLNRY03j2Aic2LdsNLEn/XgLsDiDOdwLPkPYxhRxri9g/CPxjyPGSXBXuF8AJJBMf3g9cFuK2C/wecHvD4/8E/HFo6xYYA3Y2PG4ZH/BXwCdaPW+QW2wt+plSyOPAAeBBwr584V+QbHS/Sh8PE26skFzz9/tmtiO9AhjAye7+XPr388DJ5YR2hGXAFPCttCz212Z2LGHG2uzjwF3p30HG6+77gT8D9gHPAa+QXDI0xG13J/BeMxs2syHgw8CpBLpuG7SLb2YnOyOT9Rxdonf3tzw5BB4hOVzr+vKFRTKzK4AD7r6j7Fh6cKG7n0Ny+Pg5M7uo8R89aWKEMExrHnAOcJu7nw38kqZD84BiPSytaX8E+Lvmfwsp3rRevJZkh/obwLEcXXoIgrvvIikpfR/4HvA48FbTc4JZt60UEV90iX6G93H5woJdAHzEzPYCd5OUb75GmLECh1tyuPsBkhryucALZrYEIL0/UF6Eh00Ck+7+aPp4K0niDzHWRh8CHnP3F9LHocZ7KfCMu0+5+yHgOyTbc5Dbrrvf7u6r3f0ikr6DfybcdTujXXz7SY5IZmSynqNK9Jbz5Quz5O5/4u4j7j5Gcrj+sLuvI8BYAczsWDM7fuZvklryTuA+kjghkHjd/XngF2a2Ml10CfAUAcba5BO8XbaBcOPdB5xnZkNmZry9fkPddk9K75cCvwvcSbjrdka7+O4Dfj8dfXMe8Er6Wd+VAAAAxklEQVRDiad/ZXZQ9NGh8W6SyxP+hCQJ/ed0+W8C/wTsITks/rWyY22K+7eB+0OONY3rifT2JPCVdPkwSYfy08BDwAllx5rGtQqYSLeF7wKLQo01jfdYYBp4Z8OykOP9U+Bn6e/sDuDXAt52/4FkR/QEcElo65Zk5/4ccIjkaPS6dvGRDNi4laTv8ackI58GjkFnxoqIVFxUpRsREemdEr2ISMUp0YuIVJwSvYhIxSnRi4hUnBK9iEjFKdGLiFScEr2ISMX9f4R5L+BCAg6jAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fe2541c0128>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 获取并查看数据\n",
    "\n",
    "with open('data.txt') as f :\n",
    "    data = f.read().split('\\n')\n",
    "    data = [row.split(',') for row in data][:-1]\n",
    "    label0 = np.array([(float(row[0]), float(row[1])) for row in data if row[2] == '0'])\n",
    "    label1 = np.array([(float(row[0]), float(row[1])) for row in data if row[2] == '1'])\n",
    "x0, y0 = label0[:, 0], label0[:, 1]\n",
    "x1, y1 = label1[:, 0], label1[:, 1]\n",
    "plt.plot(x0, y0, 'ro', label = 'label_0')\n",
    "plt.plot(x1, y1, 'bo', label = 'label_1')\n",
    "plt.legend(loc = 'best')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "\n",
    "# 获得训练数据\n",
    "x = np.concatenate((label0, label1), axis = 0)\n",
    "x_data = torch.from_numpy(x).float()\n",
    "\n",
    "y = [[0] for i in range(label0.shape[0])]\n",
    "y += [[1] for i in range(label1.shape[0])]\n",
    "y_data = torch.FloatTensor(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义模型\n",
    "\n",
    "class logisticRegression(nn.Module) :\n",
    "    def __init__(self) :\n",
    "        super().__init__()\n",
    "        self.line = nn.Linear(2, 1)\n",
    "        self.smd = nn.Sigmoid()\n",
    "    def forward(self, x) :\n",
    "        x = self.line(x)\n",
    "        return self.smd(x)\n",
    "\n",
    "logistic = logisticRegression()\n",
    "\n",
    "if torch.cuda.is_available() :\n",
    "    logistic.cuda()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义损失函数为二分类交叉熵(Binary Cross Entropy)\n",
    "criterion = nn.BCELoss()\n",
    "# 定义优化函数为随机梯度下降(Sochastic Gradient Descent)\n",
    "optimizer = optim.SGD(logistic.parameters(), lr = 1e-3, momentum = 0.9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "解释一下两个部分\n",
    "\n",
    "#### BCELoss()\n",
    "它的定义是 $loss(o, t) = \\frac 1 n \\sum_i(t[i] * log(o[i]) + (1 - t[i]) * log(1 - o[i]))$\n",
    "\n",
    "以上来源于[torch.nn.BCELoss](http://pytorch.org/docs/master/nn.html?highlight=nn%20bceloss#torch.nn.BCELoss)\n",
    "#### SGD函数，它带有一个参数 `momentum = 0.9`，这表示动量。\n",
    "\n",
    "这种优化方法来源于[On the importance of initialization and momentum in deep learning](http://www.cs.toronto.edu/~hinton/absps/momentum.pdf)\n",
    "\n",
    "它的优化方式为 : $$v = \\rho * v + g \\\\ p = p - lr * v$$\n",
    "其中，p, g, v, $\\rho$ 分别表示待更新的参数parameters，求得的梯度gradient，速度velocity，和动量momentum\n",
    "\n",
    "以上来源于[官网](http://pytorch.org/docs/master/optim.html)关于torch.optim.SGD的note"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "**********\n",
      "epoch 10000\n",
      "loss is 0.3826\n",
      "correct rate is 0.9100\n",
      "**********\n",
      "epoch 20000\n",
      "loss is 0.3146\n",
      "correct rate is 0.9200\n",
      "**********\n",
      "epoch 30000\n",
      "loss is 0.2826\n",
      "correct rate is 0.9100\n",
      "**********\n",
      "epoch 40000\n",
      "loss is 0.2640\n",
      "correct rate is 0.9100\n",
      "**********\n",
      "epoch 50000\n",
      "loss is 0.2517\n",
      "correct rate is 0.9100\n"
     ]
    }
   ],
   "source": [
    "# 开始训练\n",
    "epoches = 50000\n",
    "for epoch in range(epoches) :\n",
    "    if torch.cuda.is_available() :\n",
    "        x = Variable(x_data).cuda()\n",
    "        y = Variable(y_data).cuda()\n",
    "    else :\n",
    "        x = Variable(x_data)\n",
    "        y = Variable(y_data)\n",
    "    \n",
    "    # forward 前向计算\n",
    "    out = logistic(x)\n",
    "    loss = criterion(out, y)\n",
    "    \n",
    "    # 计算准确率\n",
    "    print_loss = loss.data[0]\n",
    "    mask = out.ge(0.5).float()\n",
    "    # print('size : {} - {}'.format(mask.size(), y.size()))\n",
    "    correct = (mask == y).sum()\n",
    "    acc = correct.data[0] / x.size(0)\n",
    "    \n",
    "    # BP回朔\n",
    "    optimizer.zero_grad()\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "    if (epoch + 1) % 10000 == 0 :\n",
    "        print('*' * 10)\n",
    "        print('epoch {}'.format(epoch + 1))\n",
    "        print('loss is {:.4f}'.format(print_loss))\n",
    "        print('correct rate is {:.4f}'.format(acc))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fe259d39320>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "weight = logistic.line.weight.data[0]\n",
    "w0, w1 = weight[0], weight[1]\n",
    "b = logistic.line.bias.data[0]\n",
    "\n",
    "plt.plot(x0, y0, 'ro', label = 'label_0')\n",
    "plt.plot(x1, y1, 'bo', label = 'label_1')\n",
    "plt.legend(loc = 'best')\n",
    "plot_x = np.arange(30, 100, 0.1)\n",
    "plot_y = (-w0 * plot_x - b) / w1\n",
    "plt.plot(plot_x, plot_y)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
